package com.pm.buglist.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pm.buglist.domain.*;
import com.pm.buglist.domain.vo.ImportBug;
import com.pm.buglist.domain.vo.OaWaiveParam;
import com.pm.buglist.domain.vo.ProjectBugVo;
import com.pm.buglist.mapper.*;
import com.pm.buglist.service.BugsService;
import com.pm.common.OAService;
import com.pm.common.config.ParamConfig;
import com.pm.common.constant.ProjectConstants;
import com.pm.common.core.domain.AjaxResult;
import com.pm.common.core.domain.entity.SysRole;
import com.pm.common.core.domain.entity.SysUser;
import com.pm.common.core.domain.model.LoginUser;
import com.pm.common.enums.BugsStatus;
import com.pm.common.enums.DictDateKey;
import com.pm.common.enums.OaStatus;
import com.pm.common.enums.RoleKey;
import com.pm.common.exception.UtilException;
import com.pm.common.utils.*;
import com.pm.system.mapper.SysDictDataMapper;
import com.pm.system.mapper.SysUserMapper;
import com.github.yitter.contract.IdGeneratorException;
import com.github.yitter.idgen.YitIdHelper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.text.ParseException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;


/**
 * <p>
 * 项目bugs列表 服务实现类
 * </p>
 *
 * @author wwm
 * @since 2023-12-14
 */
@Service
public class BugsServiceImpl extends ServiceImpl<BugsMapper, Bugs> implements BugsService {

    @Resource
    private BugsMapper bugsMapper;

    @Resource
    private BugDescriptionMapper descriptionMapper;

    @Resource
    private BugAnalysisMapper analysisMapper;

    @Resource
    private BugsHandleLogMapper handleLogMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private BugsRdHandleMapper rdHandleMapper;

    @Resource
    private BugsQdeHandleMapper qdeHandleMapper;

    @Resource
    private SysUserMapper userMapper;

    @Resource
    private WeChatNoteUtils weChatNoteUtils;

    @Resource
    private WeChatUtils weChatUtils;

    @Resource
    private BugsHandleLogMapper bugsHandleLogMapper;

    @Resource
    private ParamConfig paramConfig;

    @Resource
    private ProjectMapper projectMapper;

    @Resource
    private SysDictDataMapper dictDataMapper;

    @Resource
    private TranferLogMapper tranferLogMapper;

    @Resource
    private WavieOrderMapper wavieOrderMapper;

    @Resource
    private OaUtils oaUtils;

    @Resource
    private RedisLockRegistry redisLockRegistry;//分布式锁


    @Resource
    OAService oaService;

    /**
     * 查询项目bugs列
     *
     * @param id 项目bugs列主键
     * @return 项目bugs列
     */
    @Override
    public Bugs selectBugsById(Long id)
    {
        Bugs bugs = bugsMapper.selectBugsById(id);
        List<BugsRdHandle> rdHandleList = rdHandleMapper.findBugsRdHandleByBid(id);
        List<Long> collect = rdHandleList.stream().map(item -> {
            return item.getUserId();
        }).collect(Collectors.toList());
        bugs.setRdHandle(collect);
        return bugs;
    }

    /**
     * 查询项目bugs列列表
     *
     * @param bugs 项目bugs列
     * @return 项目bugs列
     */
    @Override
    public List<Bugs> selectBugsList(Bugs bugs)
    {
        //获取登录用户信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<Bugs> bugsList=new ArrayList<>();
        String queryKey = bugs.getQueryKey();
        if(!StringUtils.isEmpty(queryKey) && queryKey.equals("3")){//指派给我的
            //判断用户身份
            List<SysRole> roles = loginUser.getUser().getRoles();
            Boolean rdFlag=false;
            Boolean qdeFlag=false;
            Boolean npiFlag=false;
            Boolean gysFlag=false;
            if(!CollectionUtils.isEmpty(roles)){
                for (SysRole role : roles) {
                    String roleKey = role.getRoleKey();
                    if(roleKey.equals(RoleKey.DQE.getCode()) || roleKey.equals(RoleKey.DQA.getCode()) ||
                            roleKey.equals(RoleKey.ADMIN.getCode())){//品质
                        qdeFlag=true;
                        break;
                    }else if(roleKey.equals(RoleKey.RD.getCode())){//研发
                        rdFlag=true;
                        break;
                    }else if(roleKey.equals(RoleKey.WBGYS.getCode())){//外部供应商
                        gysFlag = true;
                        break;
                    }else if(roleKey.equals(RoleKey.NPI.getCode())){//npi角色
                        npiFlag=true;
                        break;
                    }
                }
            }
            if(qdeFlag){//品质
                bugs.setQdeHandleUser(loginUser.getUserId());
                bugsList =assignQdeBugsList(bugs);
            }else if(rdFlag){//研发
                bugs.setRdHandleUser(loginUser.getUserId());
                bugsList= assignRdBugsList(bugs);
            }else if(gysFlag){//外部供应商
                bugs.setRdHandleUser(loginUser.getUserId());
                List<GYSBugs> gysBugsList= assignGYSBugsList(bugs);
                if(CollectionUtils.isEmpty(gysBugsList)){

                    for (GYSBugs gysBugs : gysBugsList) {
                        Bugs bug = new Bugs();
                        BeanUtils.copyProperties(gysBugs,bug);
                        bugsList.add(bug);
                    }
                }


            } else if(npiFlag){//npi
                bugs.setQdeHandleUser(loginUser.getUserId());
                bugs.setRdHandleUser(loginUser.getUserId());
                bugsList=baseMapper.selectAssignNpiBugList(bugs);
            }
        }else if(!StringUtils.isEmpty(queryKey) && queryKey.equals("5")){//研发查询已处理的数据
            bugs.setRdHandleUser(loginUser.getUserId());
            bugsList=baseMapper.rdBugListProcessed(bugs);
        }else {
            if(!StringUtils.isEmpty(queryKey) && queryKey.equals("4")){
                bugs.setCreateUser(loginUser.getUserId());
            }else if(!StringUtils.isEmpty(queryKey) && queryKey.equals("2")){
                bugs.setNoCloseFlag("1");
            }
            bugsList = bugsMapper.selectBugsList(bugs);
        }

        return bugsList;
    }

    /**
     * 外部供应商查询BUG
     * @param bugs
     * @return
     */
    @Override
    public List<GYSBugs> assignGYSBugsList(Bugs bugs) {
        LoginUser loginUser =SecurityUtils.getLoginUser();
        bugs.setRdHandleUser(loginUser.getUserId());
        String queryKey = bugs.getQueryKey();
        List<GYSBugs> bugsList = new ArrayList<>();
        if(!StringUtils.isEmpty(queryKey) && queryKey.equals("3")){//待处理
            bugsList = bugsMapper.assignGYSBugsList(bugs);
        }else{//已处理
            bugsList=baseMapper.gysBugListProcessed(bugs);
        }
        return bugsList;
    }

    /**
     * 查询指派给研发的bug数据
     * @param bugs
     * @return
     */
    @Override
    public List<Bugs> assignRdBugsList(Bugs bugs) {
        return bugsMapper.selectAssignRdBugsList(bugs);
    }

    /**
     * 指派给品质的bug数据
     * */
    @Override
    public List<Bugs> assignQdeBugsList(Bugs bugs) {
        return bugsMapper.selectAssignQdeBugsList(bugs);
    }


    /**
     * 新增项目bugs列
     *
     * @param bugs 项目bugs列
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public int insertBugs(Bugs bugs){
        try {
            //获取到指派人
            List<Long> rdHandle = bugs.getRdHandle();
            if(CollectionUtils.isEmpty(rdHandle)){
               throw new RuntimeException("指派人不能为空");
            }
            //验证bug描述不能为空
            String descriptions = bugs.getDescriptions();
            String s = com.pm.common.utils.StringUtils.filterHtmlTags(descriptions).replaceAll(" ","");
            if(StringUtils.isEmpty(s)){
               throw new RuntimeException("bug描述内容不能为空");
            }
            //生成id
            long id = YitIdHelper.nextId();
            bugs.setId(id);
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();
            List<SysRole> roles = loginUser.getUser().getRoles();
            Boolean flag=false;
            if(!CollectionUtils.isEmpty(roles)){
                for (SysRole role : roles) {
                    if(role.getRoleKey().equals(RoleKey.NPI.getCode())){
                        flag=true;
                        break;
                    }
                }
            }
            if(flag){
                bugs.setIdentify("N");//工厂NPI标识(试投bug)
            }else {
                bugs.setIdentify("T");//测试bug
            }
            bugs.setBugStatus(BugsStatus.OPEN.getStatus());//默认是open状态
//            if(!ObjectUtils.isEmpty(bugs.getHandleStatus())){
                bugs.setHandleStatus("0");//新创建时默认处理角色是指派人
//            }
            bugs.setBugCode(createCode());//生成唯一的code
            bugs.setCreateUser(userId);
            bugs.setCreateTime(LocalDateTime.now());
            int i = bugsMapper.insertBugs(bugs);

            //插入rd/qde指派人
            for (Long uId : rdHandle) {
                BugsRdHandle bugsRdHandle = new BugsRdHandle();
                bugsRdHandle.setBugId(id);
                bugsRdHandle.setStatus("1");//插入时为最新处理人
                bugsRdHandle.setUserId(uId);//处理人
                bugsRdHandle.setCreateUser(userId);
                bugsRdHandle.setCreateTime(LocalDateTime.now());
                rdHandleMapper.insert(bugsRdHandle);
            }
            //品质指派人
            BugsQdeHandle bugsQdeHandle = new BugsQdeHandle();
            bugsQdeHandle.setBugId(id);
            bugsQdeHandle.setStatus("1");
            bugsQdeHandle.setUserId(userId);//品质指派人就是创建人
            bugsQdeHandle.setCreateUser(userId);
            bugsQdeHandle.setCreateTime(LocalDateTime.now());
            qdeHandleMapper.insert(bugsQdeHandle);

            if(i>0){
                String bugVersion = bugs.getBugVersion();
                //插入bugs之后添加bugs描述
                BugDescription bugDescription = new BugDescription();
                bugDescription.setBugId(id);
                bugDescription.setDescriptions(bugs.getDescriptions());
                bugDescription.setStatus("1");//发布的状态
                bugDescription.setVersion(bugVersion);
                bugDescription.setCreateUser(userId);
                bugDescription.setHandleUser(userId);
                bugDescription.setCreateTime(LocalDateTime.now());
                int insert = descriptionMapper.insert(bugDescription);

                //插入描述之后插入预确认的bug分析
                BugAnalysis bugAnalysis = new BugAnalysis();
                bugAnalysis.setBugId(id);
                bugAnalysis.setBdId(bugDescription.getId());
                bugAnalysis.setStatus("0");//草稿的状态
                analysisMapper.insert(bugAnalysis);

                //记录bug处理日志
                BugsHandleLog bugsHandleLog = new BugsHandleLog();
                bugsHandleLog.setBugId(id);
                bugsHandleLog.setBugStatus(bugs.getBugStatus());
                bugsHandleLog.setBugTitle(bugs.getBugTitle());
                bugsHandleLog.setHandleStatus("1");//新建时的处理人身份为品质/NPI
                bugsHandleLog.setVersion(bugs.getBugVersion());
                bugsHandleLog.setHandleUser(userId);
                bugsHandleLog.setCreateTime(LocalDateTime.now());
                handleLogMapper.insert(bugsHandleLog);



                //添加完毕之后，发送企业微信消息通知
                List<String> noticUsers=new ArrayList<>();
                for (Long aLong : rdHandle) {
                    SysUser sysUser = userMapper.selectUserById(aLong);
                    if(!ObjectUtils.isEmpty(sysUser)){
                        String companyWechatId = sysUser.getCompanyWechatId();
                        noticUsers.add(companyWechatId);
                    }
                }
                Project project = projectMapper.selectById(bugs.getPid());
                String subject = project.getProjectNo()+"项目,机型:"+project.getModel()+"有新增BUG,请及时登陆PM系统处理!";
                String token = weChatUtils.getAccessToken();
                AjaxResult res = weChatUtils.sendTextMessage(token,subject,noticUsers);
                if(res.isError()){
                    log.error("创建BUG 发送企业微信消息给处理人错误:"+res.get(AjaxResult.MSG_TAG));
                }
//                oaService.createWaitTaskNotice("/bugs/list?pageNum=1&pageSize=5&queryKey=3",jobNumber,subject);
                //添加完毕之后，发送企业微信消息通知
//                new Thread(()->{
//                    List<String> jobNumber=new ArrayList<>();
//                    for (Long aLong : rdHandle) {
//                        SysUser sysUser = userMapper.selectUserById(aLong);
//                        if(!ObjectUtils.isEmpty(sysUser)){
//                            String jobNumber1 = sysUser.getJobNumber();
//                            if(!StringUtils.isEmpty(jobNumber1)){
//                                jobNumber.add(jobNumber1);
//                            }
//                        }
//                    }
//                    String userName="";
//                    SysUser sysUser = userMapper.selectUserById(userId);
//                    if(!ObjectUtils.isEmpty(sysUser)){
//                        userName=sysUser.getUserName();
//                    }
//                    String msg="你好,"+userName+"向你提报了一个待处理的项目bug，bug编码为："+bugs.getBugCode();
//                    String msg1="请你尽快登录bugList系统进行处理，谢谢。系统登录链接为："+paramConfig.getLink();
//                    List<String> mesage=new ArrayList<>();
//                    mesage.add(msg);
//                    mesage.add(msg1);
//                    weChatNoteUtils.sendWeChatNoteByJobNumber(jobNumber,mesage);
//                }).start();
            }
            return i;
        } catch (IdGeneratorException e) {
            e.printStackTrace();
            log.error("创建bug异常:"+ JSONObject.toJSONString(e));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new RuntimeException("创建异常");
        }
    }


//    private void createWaitTaskNotice(String redirect,List<JSONObject> toUsers,String subject) {
//
//        JSONObject param = new JSONObject();
//        param.put("appName", ProjectConstants.PM);
//        param.put("modelName",ProjectConstants.OA_TODO_MODEL_NAME);
//        param.put("modelId",ProjectConstants.OA_TODO_MODEL_ID);
//        param.put("subject",subject);
//        String url = paramConfig.getOaAddr()+"/pro/sso/proSsoRequest.do?method=login&service="+ URLEncoder.encode(paramConfig.getPmAddr() +"/login?redirect="+redirect) ;
//        param.put("link", url);
//        param.put("mobileLink",url);
//        param.put("padLink",url);
//        param.put("type","1");
//
//        param.put("targets",JSONObject.toJSONString(toUsers));
//        param.put("createTime", DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS));
//
//        AjaxResult res = oaService.sendTodo(param);
//
//    }

    /**
     * 修改项目bugs列
     *
     * @param bugs 项目bugs列
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult updateBugs(Bugs bugs){
        try {
            //获取登录人信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();
            Long id = bugs.getId();
            Bugs bugs1 = baseMapper.selectById(id);
            //判断bug是否是当前登录人创建的
            if(!loginUser.getUser().isAdmin()){//管理员免校验
                if(!bugs1.getCreateUser().equals(userId)){
                    return AjaxResult.error("你不是当前bug的创建人，无权修改");
                }
            }

            //验证bug描述不能为空
            String descriptions = bugs.getDescriptions();
            String s = com.pm.common.utils.StringUtils.filterHtmlTags(descriptions).replaceAll(" ","");
            if(StringUtils.isEmpty(s)){
                return AjaxResult.error("bug描述内容不能为空");
            }
            List<Long> rdHandle = bugs.getRdHandle();
            if(CollectionUtils.isEmpty(rdHandle)){
                return AjaxResult.error("指派人不能为空");
            }
            //最新的指派处理人
            List<BugsRdHandle> rdHandleList = rdHandleMapper.findBugsRdHandleByBid(id);
            if(CollectionUtils.isEmpty(rdHandleList)){
                return AjaxResult.error("找不到当前最新处理人");
            }
            List<Long> collect1 = rdHandleList.stream().map(item -> {
                return item.getUserId();
            }).collect(Collectors.toList());
            List<Long> collect2 = rdHandle.stream().filter(item -> {
                return !collect1.contains(item);
            }).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(collect2)){//判断是否修改指派人

                List<Integer> collect = rdHandleList.stream().map(item -> {
                    return item.getId();
                }).collect(Collectors.toList());

                int i = rdHandleMapper.deleteBatchIds(collect);//先删除最新处理人
                if(i>0){
                    //插入rd指派人
                    for (Long uId : rdHandle) {
                        BugsRdHandle bugsRdHandle = new BugsRdHandle();
                        bugsRdHandle.setBugId(id);
                        bugsRdHandle.setStatus("1");//插入时为最新处理人
                        bugsRdHandle.setUserId(uId);//处理人
                        bugsRdHandle.setCreateUser(userId);
                        bugsRdHandle.setCreateTime(LocalDateTime.now());
                        rdHandleMapper.insert(bugsRdHandle);
                    }
                }
            }

            //修改最新的描述
            BugDescription newDescription = descriptionMapper.findBugDescriptionByBid(id);
            newDescription.setDescriptions(descriptions);//修改最新描述

            descriptionMapper.updateById(newDescription);

            //修改bug信息
            bugs.setUpdateTime(LocalDateTime.now());
            bugs.setUpdateUser(userId);
            bugsMapper.updateBugs(bugs);
            return AjaxResult.success("修改成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("修改bug异常:"+e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("修改异常");
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult closeBugsById(Bugs bug) {
        try {
            Long id = bug.getId();
            List<Long> ids = bug.getIds();
            //获取登录用户信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();
            //验证用户是否是管理员或者是dqa
            Boolean flag = checkRole(loginUser);
            if(!ObjectUtils.isEmpty(id)){//单个关闭
                //查询到bug信息
                Bugs bugs = bugsMapper.selectBugsById(id);
                if(!flag){//确认不是管理员与dqa的身份之后，确认是否是bugs创建人
                    flag=checkBugCreate(bugs,userId);
                }
                if(!flag){
                    return AjaxResult.error("你没有权限关闭此bug");
                }
                if(bugs.getBugStatus().equals(BugsStatus.OPEN.getStatus())){//判断bugs的状态是否为open
                    return AjaxResult.error("此bug的状态为open,不能关闭");
                }
                //执行关闭操作
                bugs.setBugStatus(BugsStatus.CLOSE.getStatus());//设置关闭
                bugs.setUpdateTime(LocalDateTime.now());
                bugs.setUpdateUser(userId);
                baseMapper.updateById(bugs);

                //修改分析标注
                BugAnalysis bugAnalysis = analysisMapper.selectBugAnalysisByBid(id);
                bugAnalysis.setIsClose("1");//关闭标注
                analysisMapper.updateById(bugAnalysis);
                //记录bug处理日志
                BugsHandleLog bugsHandleLog = new BugsHandleLog();
                bugsHandleLog.setBugId(bugs.getId());
                bugsHandleLog.setBugStatus(bugs.getBugStatus());
                bugsHandleLog.setBugTitle(bugs.getBugTitle());
                bugsHandleLog.setVersion(bugAnalysis.getVersion());//最新的版本
                bugsHandleLog.setHandleUser(userId);
                bugsHandleLog.setCreateTime(LocalDateTime.now());
                handleLogMapper.insert(bugsHandleLog);

                return AjaxResult.success("关闭成功");
            }else if(!CollectionUtils.isEmpty(ids)){
                //用来存储没有权限操作的bugs的bugCode
                List<String> bugCode=new ArrayList<>();
                //用户存储状态为open的bug的bugCode
                List<String> openStatus=new ArrayList<>();
                if(!flag){//确认不是管理员与dqa的身份之后，确认是否是bugs创建人
                    for (Long bid : ids) {
                        Bugs bugs = bugsMapper.selectBugsById(bid);
                        boolean b = checkBugCreate(bugs,userId);
                        if(!b){//没有权限的数据存储到list里面
                            bugCode.add(bugs.getBugCode());
                        }
                        //验证bug的状态
                        if(bugs.getBugStatus().equals(BugsStatus.OPEN.getStatus())){//判断bugs的状态是否为open
                            openStatus.add(bugs.getBugCode());
                        }
                    }
                }else {//如果是管理员/dqa验证一下bug的状态
                    for (Long bid : ids) {
                        Bugs bugs = bugsMapper.selectBugsById(bid);
                        if(bugs.getBugStatus().equals(BugsStatus.OPEN.getStatus())){//判断bugs的状态是否为open
                            openStatus.add(bugs.getBugCode());
                        }
                    }
                }
                //判断是否有没有权限操作的bug
                if(!CollectionUtils.isEmpty(bugCode)){
                    return AjaxResult.error("bug编码为这些"+bugCode.toString()+"的bug,你没有权限关闭");
                }
                //判断是否有bug为open状态的
                if(!CollectionUtils.isEmpty(openStatus)){
                    return AjaxResult.error("bug编码为这些"+openStatus.toString()+"的bug状态为open,不能关闭");
                }
                //执行关闭操作
                for (Long aLong : ids) {
                    Bugs bugs = new Bugs();
                    bugs.setId(aLong);
                    bugs.setBugStatus(BugsStatus.CLOSE.getStatus());//设置关闭
                    bugs.setUpdateTime(LocalDateTime.now());
                    bugs.setUpdateUser(userId);
                    baseMapper.updateById(bugs);

                    //修改分析标注
                    BugAnalysis bugAnalysis = analysisMapper.selectBugAnalysisByBid(aLong);
                    bugAnalysis.setIsClose("1");//关闭标注
                    analysisMapper.updateById(bugAnalysis);

                    //记录bug处理日志
                    BugsHandleLog bugsHandleLog = new BugsHandleLog();
                    bugsHandleLog.setBugId(bugs.getId());
                    bugsHandleLog.setBugStatus(bugs.getBugStatus());
                    bugsHandleLog.setBugTitle(bugs.getBugTitle());
                    bugsHandleLog.setVersion(bugAnalysis.getVersion());//最新的关闭版本
                    bugsHandleLog.setHandleUser(userId);
                    bugsHandleLog.setCreateTime(LocalDateTime.now());
                    handleLogMapper.insert(bugsHandleLog);
                }
                return AjaxResult.success("关闭成功");
            }else {
                return AjaxResult.error("操作的数据不能为空!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("bug关闭异常:"+JSONObject.toJSONString(e));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("关闭异常");
        }
    }

    private boolean checkRole(LoginUser loginUser){
        boolean admin = loginUser.getUser().isAdmin();
        List<SysRole> roles = loginUser.getUser().getRoles();
        Boolean flag=false;
        if(admin){//如果是管理员
            flag=true;
        }else {
            if (!CollectionUtils.isEmpty(roles)) {
                for (SysRole role : roles) {
                    String roleKey = role.getRoleKey();
                    if (roleKey.equals(RoleKey.DQA.getCode()) || role.getRoleKey().equals(RoleKey.ADMIN.getCode())) {//dqa与admin
                        flag = true;
                        break;
                    }
                }
            }
        }
        return flag;
    }

    private boolean checkBugCreate(Bugs bugs,Long userId){
        Boolean flag=false;
        if(!ObjectUtils.isEmpty(bugs)) {
            if (bugs.getCreateUser().equals(userId)) {//判断是否是bug创建人
                flag = true;
            }
        }
        return flag;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult waiveBugsById(Bugs bug) {
        try {
            Long id = bug.getId();
            List<Long> ids = bug.getIds();
            //获取登录用户信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();
            //验证用户是否是管理员或者是dqa
            Boolean flag = checkRole(loginUser);
            if(!ObjectUtils.isEmpty(id)){//单个废弃
                //查询到bug信息
                Bugs bugs = bugsMapper.selectBugsById(id);
                if(!flag){//确认不是管理员与dqa的身份之后，确认是否是bugs创建人
                    flag=checkBugCreate(bugs,userId);
                }
                if(!flag){
                    return AjaxResult.error("你没有权限废弃此bug");
                }
                if(bugs.getBugStatus().equals(BugsStatus.OPEN.getStatus())){
                    return AjaxResult.error("OPEN状态的bug不允许waive");
                }

                String lockKey="waive_key:"+id;
                //加锁
                Lock waiveLock = redisLockRegistry.obtain(lockKey);
                try {
                    waiveLock.lock();
                    //先检测是否已经操作
                    String operation = (String) redisTemplate.opsForValue().get(lockKey);
                    if(!StringUtils.isEmpty(operation)){
                        return AjaxResult.error("该bug已经被废弃,请勿重复操作！！");
                    }
                    //执行废弃操作
                    bugs.setBugStatus(BugsStatus.WAIVE.getStatus());//设置废弃
                    bugs.setUpdateTime(LocalDateTime.now());
                    bugs.setUpdateUser(userId);
                    baseMapper.updateById(bugs);
                    //查找最新的描述
                    BugDescription description = descriptionMapper.findBugDescriptionByBid(id);
                    //记录bug处理日志
                    BugsHandleLog bugsHandleLog = new BugsHandleLog();
                    bugsHandleLog.setBugId(bugs.getId());
                    bugsHandleLog.setBugStatus(bugs.getBugStatus());
                    bugsHandleLog.setBugTitle(bugs.getBugTitle());
                    if(!ObjectUtils.isEmpty(description)){
                        bugsHandleLog.setVersion(description.getVersion());//最新的版本
                    }
                    bugsHandleLog.setHandleUser(userId);
                    bugsHandleLog.setCreateTime(LocalDateTime.now());
                    handleLogMapper.insert(bugsHandleLog);

                    //修改waive_Order中的状态为通过
                    WavieOrder wavieOrder = new WavieOrder();
                    wavieOrder.setBId(id);
                    wavieOrder.setUpdateUser(userId);
                    wavieOrderMapper.updateWaiveOrderByBid(wavieOrder);
                    redisTemplate.opsForValue().set(lockKey,"ok",24,TimeUnit.HOURS);
                    return AjaxResult.success("废弃成功");
                } finally {
                    waiveLock.unlock();
                }
            }else if(!CollectionUtils.isEmpty(ids)){//批量废弃
                //用来存储没有权限操作的bugs的bugCode
                List<String> bugCode=new ArrayList<>();
                //用来存储校验bugs状态为open的bugCode
                List<String> openCode=new ArrayList<>();
                //用来存储根据id查询出来的bug
                List<Bugs> blist=new ArrayList<>();
                //根据id查bug
                for (Long bid : ids) {
                    Bugs bugs = bugsMapper.selectBugsById(bid);
                    blist.add(bugs);
                }
                if(!flag){//确认不是管理员与dqa的身份之后，确认是否是bugs创建人
                    for (Bugs bugs : blist) {
                        String bcode = bugs.getBugCode();
                        boolean b = checkBugCreate(bugs,userId);
                        if(!b){//没有权限的数据存储到list里面
                            bugCode.add(bcode);
                        }

                    }
                }
                //判断bug状态是否为Open
                for (Bugs bugs : blist) {
                    if(bugs.getBugStatus().equals(BugsStatus.OPEN.getStatus())){
                        openCode.add(bugs.getBugCode());
                    }
                }
                //判断是否有没有权限操作的bug
                if(!CollectionUtils.isEmpty(bugCode)){
                    return AjaxResult.error("bug编码为这些"+bugCode.toString()+"的bug不是你创建的,你没有权限废弃");
                }
                //判断是否有bug当前是open的状态,不允许waive
                if(!CollectionUtils.isEmpty(openCode)){
                    return AjaxResult.error("bug编码为这些"+openCode.toString()+"的bug状态为open状态,不允许waive");
                }

                String lockKey="waive_key:"+ids.toString();
                //加锁
                Lock waiveLock = redisLockRegistry.obtain(lockKey);

                try {
                    waiveLock.lock();
                    //先检测是否已经操作
                    String operation = (String) redisTemplate.opsForValue().get(lockKey);
                    if(!StringUtils.isEmpty(operation)){
                        return AjaxResult.error("这些bug已经被废弃,请勿重复操作！！");
                    }
                    WavieOrder wavieOrder = new WavieOrder();
                    wavieOrder.setUpdateUser(userId);
                    //执行废弃操作
                    for (Long aLong : ids) {
                        Bugs bugs = new Bugs();
                        bugs.setId(aLong);
                        bugs.setBugStatus(BugsStatus.WAIVE.getStatus());//设置废弃
                        bugs.setUpdateTime(LocalDateTime.now());
                        bugs.setUpdateUser(userId);
                        baseMapper.updateById(bugs);

                        //查找最新的描述
                        BugDescription description = descriptionMapper.findBugDescriptionByBid(id);

                        //记录bug处理日志
                        BugsHandleLog bugsHandleLog = new BugsHandleLog();
                        bugsHandleLog.setBugId(bugs.getId());
                        bugsHandleLog.setBugStatus(bugs.getBugStatus());//bug状态
                        bugsHandleLog.setBugTitle(bugs.getBugTitle());//bug标题
                        if(!ObjectUtils.isEmpty(description)){
                            bugsHandleLog.setVersion(description.getVersion());//最新的版本
                        }
                        bugsHandleLog.setHandleUser(userId);
                        bugsHandleLog.setCreateTime(LocalDateTime.now());
                        handleLogMapper.insert(bugsHandleLog);

                        //修改waive_Order中的状态为通过
                        wavieOrder.setBId(aLong);
                        wavieOrderMapper.updateWaiveOrderByBid(wavieOrder);
                    }
                    return AjaxResult.success("废弃成功");
                } finally {
                    waiveLock.unlock();
                }

            }else {
                return AjaxResult.error("操作的数据不能为空!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("废弃bug异常:"+JSONObject.toJSONString(e));
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("废弃异常");
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult handleProjectBug(Bugs bugs) {
        try {
            Long bid = bugs.getId();
            if(ObjectUtils.isEmpty(bid)){
                return AjaxResult.error("处理的数据不能为空");
            }
            //根据id获取bug信息
            Bugs bugs1 = baseMapper.selectBugsById(bid);
            String oldBugStatus = bugs1.getBugStatus();
            //验证当前bug的状态
            if(oldBugStatus.equals(BugsStatus.WAIVE.getStatus())||oldBugStatus.equals(BugsStatus.CLOSE.getStatus())){
                return AjaxResult.success("此bug已关闭/废弃,不能再进行处理操作");
            }
            //验证用户是否有权限执行操作
            //获取用户登录信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();
            boolean admin = loginUser.getUser().isAdmin();
//            Boolean flag=false;
//            if(admin){
//                flag=true;
//            }else {
//                //验证用户身份
//                List<SysRole> roles = loginUser.getUser().getRoles();
//                if(!CollectionUtils.isEmpty(roles)){
//                    for (SysRole role : roles) {
//                        String roleKey = role.getRoleKey();
//                        if(roleKey.equals(RoleKey.DQE.getCode()) || roleKey.equals(RoleKey.DQA.getCode())
//                                || roleKey.equals(RoleKey.RD.getCode()) || roleKey.equals(RoleKey.NPI.getCode())){
//                            flag=true;
//                            break;
//                        }
//                    }
//                }
//            }
//            if(!flag){
//                return AjaxResult.error("你没有权限操作");
//            }
            //当前操作人标记
            String handleStatus = bugs1.getHandleStatus();
            if(!admin){
                if(handleStatus.equals("0")){//当前处理人是研发
                    //查询最新的研发处理人
                    List<BugsRdHandle> rdHandles = rdHandleMapper.findBugsRdHandleByBid(bid);
                    if(!CollectionUtils.isEmpty(rdHandles)){
                        Boolean flage=false;
                        for (BugsRdHandle rdHandle : rdHandles) {
                            if(rdHandle.getUserId().equals(userId)){
                                flage=true;
                                break;
                            }
                        }
                        if(!flage){
                            return AjaxResult.error("你不是当前bug处理人,无权执行此操作");
                        }
                    }else {
                        return AjaxResult.error("找不到当前研发处理人！！");
                    }
                }else {
                    //查询最新qde处理人
                    List<BugsQdeHandle> qdeHandles = qdeHandleMapper.findBugsQdeHandleByBid(bid);
                    if(!CollectionUtils.isEmpty(qdeHandles)){
                        Boolean flage=false;
                        for (BugsQdeHandle qdeHandle : qdeHandles) {
                            if(qdeHandle.getUserId().equals(userId)){
                                flage=true;
                                break;
                            }
                        }
                        if(!flage){
                            return AjaxResult.error("你不是当前bug处理人,无权执行此操作");
                        }
                    }else {
                        return AjaxResult.error("找不到当前品质处理人！！");
                    }
                }
            }

            //插入bug 描述或者是bug分析
            if(handleStatus.equals("0")){//当前是研发
                String analysis1 = bugs.getAnalysis();
                String answer = bugs.getAnswer();
                String version = bugs.getBugVersion();
//                Long qdeHandle = bugs.getQdeHandle();//指派人
                //去除html标签再判断
                if(StringUtils.isEmpty(com.pm.common.utils.StringUtils.filterHtmlTags(analysis1)) ||
                        StringUtils.isEmpty(com.pm.common.utils.StringUtils.filterHtmlTags(answer)) ||
                        StringUtils.isEmpty(version) ){
                    return AjaxResult.error("分析/对策/版本回复不能为空");
                }
                //插入之前把原来的品质处理人设置为历史处理人
                int i = qdeHandleMapper.historyBugsQdeHandle(bid, userId);
                //插入最新的品质指派人
                BugsQdeHandle bugsQdeHandle = new BugsQdeHandle();
                bugsQdeHandle.setBugId(bid);
                bugsQdeHandle.setStatus("1");//最新
                bugsQdeHandle.setUserId(bugs1.getCreateUser());//原来的创建人
                bugsQdeHandle.setCreateUser(userId);
                bugsQdeHandle.setCreateTime(LocalDateTime.now());
                qdeHandleMapper.insert(bugsQdeHandle);
                //查询最新的描述
                BugDescription description = descriptionMapper.findBugDescriptionByBid(bid);
                Integer bdid = description.getId();
                //通过描述表id查询分析analysis
                BugAnalysis analysis = analysisMapper.selectOne(new QueryWrapper<BugAnalysis>().eq("bd_id",bdid));
                if(!ObjectUtils.isEmpty(analysis)){//判断在描述时是否已插入对应的分析数据
                    analysis.setAnalysis(analysis1);
                    analysis.setBugAnswer(answer);
                    analysis.setStatus("1");//设置为发布状态
                    analysis.setHandleUser(userId);
                    analysis.setCreateUser(userId);
                    analysis.setVersion(version);
                    analysis.setCreateTime(LocalDateTime.now());
                    analysisMapper.updateById(analysis);
                }else {
                    analysis = new BugAnalysis();
                    analysis.setBugId(bid);
                    analysis.setBdId(bdid);
                    analysis.setAnalysis(analysis1);
                    analysis.setBugAnswer(answer);
                    analysis.setStatus("1");//设置为发布状态
                    analysis.setHandleUser(userId);
                    analysis.setCreateUser(userId);
                    analysis.setVersion(version);
                    analysis.setCreateTime(LocalDateTime.now());
                    analysisMapper.insert(analysis);
                }
                //记录bug处理日志
                BugsHandleLog bugsHandleLog = new BugsHandleLog();
                bugsHandleLog.setBugId(bid);
                bugsHandleLog.setBugStatus(bugs1.getBugStatus());//研发处理的bugs状态为当前bug的状态
                bugsHandleLog.setBugTitle(bugs1.getBugTitle());//研发处理的bugs标题为当前bug的标题
                bugsHandleLog.setHandleStatus(bugs1.getHandleStatus());//处理人身份
                bugsHandleLog.setVersion(version);//版本是新的版本
                bugsHandleLog.setHandleUser(userId);
                bugsHandleLog.setCreateTime(LocalDateTime.now());
                handleLogMapper.insert(bugsHandleLog);

                //发送企业微信消息通知
                new Thread(()->{
                    //根据用户id 查询用户
                    SysUser sysUser = userMapper.selectUserById(bugsQdeHandle.getUserId());
                    if(!ObjectUtils.isEmpty(sysUser)){
                        String jobNumber = sysUser.getJobNumber();
                        String msg="你好,"+sysUser.getUserName()+",你提报的bug工程师已回复，bug编码为："+bugs1.getBugCode();
                        String msg1="请你尽快登录bugList系统进行处理，谢谢。系统登录链接为："+paramConfig.getLink();
                        List<String> mesage=new ArrayList<>();
                        mesage.add(msg);
                        mesage.add(msg1);
                        List<String> jN=new ArrayList<>();
                        jN.add(jobNumber);
                        weChatNoteUtils.sendWeChatNoteByJobNumber(jN,mesage);
                    }
                }).start();
            }else {//当前是品质
                String bugStatus = bugs.getBugStatus();
                //品质必须带有bug状态
                if(ObjectUtils.isEmpty(bugStatus)){
                    return AjaxResult.error("bug状态不能为空");
                }
                if(!bugStatus.equals(BugsStatus.CLOSE.getStatus())){//不关闭，继续描述
                    String descriptions = bugs.getNewDescriptions();
                    List<Long> rdHandle = bugs.getRdHandle();
                    if(StringUtils.isEmpty(descriptions)){
                        return AjaxResult.error("buglist补充描述不能为空");
                    }
                    //去除html标签再判断
                    String s = com.pm.common.utils.StringUtils.filterHtmlTags(descriptions);
                    String version = bugs.getBugVersion();
                    if(StringUtils.isEmpty(s) || StringUtils.isEmpty(version) || CollectionUtils.isEmpty(rdHandle)){
                        return AjaxResult.error("描述/版本/指派人不能为空!");
                    }
                    //插入之前把原来的处理人数据全部修改为历史数据
                    int i = rdHandleMapper.historyRdHandle(bid, userId);
                    //插入rd/qde指派人
                    for (Long uId : rdHandle) {
                        BugsRdHandle bugsRdHandle = new BugsRdHandle();
                        bugsRdHandle.setBugId(bid);
                        bugsRdHandle.setStatus("1");//插入时为最新处理人
                        bugsRdHandle.setUserId(uId);//处理人
                        bugsRdHandle.setCreateUser(userId);
                        bugsRdHandle.setCreateTime(LocalDateTime.now());
                        rdHandleMapper.insert(bugsRdHandle);
                    }

                    //插入新的描述
                    BugDescription bugDescription = new BugDescription();
                    bugDescription.setBugId(bid);
                    bugDescription.setDescriptions(descriptions);
                    bugDescription.setStatus("1");//发布的状态
                    bugDescription.setVersion(version);
                    bugDescription.setCreateUser(userId);
                    bugDescription.setHandleUser(userId);
                    bugDescription.setCreateTime(LocalDateTime.now());
                    descriptionMapper.insert(bugDescription);

                    //插入描述之后插入预确认的bug分析
                    BugAnalysis bugAnalysis = new BugAnalysis();
                    bugAnalysis.setBugId(bid);
                    bugAnalysis.setBdId(bugDescription.getId());
                    bugAnalysis.setStatus("0");//草稿的状态
                    analysisMapper.insert(bugAnalysis);

                    //记录bug处理日志
                    BugsHandleLog bugsHandleLog = new BugsHandleLog();
                    bugsHandleLog.setBugId(bid);
                    bugsHandleLog.setBugStatus(bugs.getBugStatus());//bug状态
                    bugsHandleLog.setBugTitle(bugs.getBugTitle());//bug标题
                    bugsHandleLog.setVersion(version);//处理版本
                    bugsHandleLog.setHandleStatus(bugs.getHandleStatus());//当前处理人身份
                    bugsHandleLog.setHandleUser(userId);
                    bugsHandleLog.setCreateTime(LocalDateTime.now());
                    handleLogMapper.insert(bugsHandleLog);

                    //发送企业微信消息通知
                    new Thread(()->{
                        List<String> jN=new ArrayList<>();
                        for (Long uid : rdHandle) {
                            //根据用户id 查询用户
                            SysUser sysUser = userMapper.selectUserById(uid);
                            if(!ObjectUtils.isEmpty(sysUser)){
                                String jobNumber = sysUser.getJobNumber();
                                jN.add(jobNumber);
                            }
                        }
                        SysUser sysUser = userMapper.selectUserById(bugs1.getCreateUser());
                        String msg="你好,"+sysUser.getUserName()+"向你提报了一个待处理的bug，bug编码为："+bugs1.getBugCode();
                        String msg1="请你尽快登录bugList系统进行处理，谢谢。系统登录链接为："+paramConfig.getLink();
                        List<String> mesage=new ArrayList<>();
                        mesage.add(msg);
                        mesage.add(msg1);
                        weChatNoteUtils.sendWeChatNoteByJobNumber(jN,mesage);
                    }).start();
                }else if(bugStatus.equals(BugsStatus.CLOSE.getStatus())) {//关闭操作记录

                    //修改分析标注
                    BugAnalysis bugAnalysis = analysisMapper.selectBugAnalysisByBid(bid);
                    bugAnalysis.setIsClose("1");//关闭标注
                    analysisMapper.updateById(bugAnalysis);

                    //记录bug处理日志
                    BugsHandleLog bugsHandleLog = new BugsHandleLog();
                    bugsHandleLog.setBugId(bid);
                    bugsHandleLog.setBugStatus(bugStatus);
                    bugsHandleLog.setBugTitle(bugs.getBugTitle());
                    bugsHandleLog.setVersion(bugs.getBugVersion());//处理版本
                    bugsHandleLog.setHandleStatus(bugs.getHandleStatus());//当前处理人身份
                    bugsHandleLog.setHandleUser(userId);
                    bugsHandleLog.setCreateTime(LocalDateTime.now());
                    handleLogMapper.insert(bugsHandleLog);
                }
            }
            //不修改bug原始版本
            bugs.setBugVersion(null);
            if(StringUtils.isEmpty(bugs.getBugStatus())){
                bugs.setBugStatus(null);
            }
            //不修改原始的问题类别
            if(StringUtils.isEmpty(bugs.getProblemType())){
                bugs.setProblemType(null);
            }
            if(StringUtils.isEmpty(bugs.getPowerSuppleId())){
                bugs.setPowerSuppleId(null);
            }
            if(StringUtils.isEmpty(bugs.getLcmOcId())){
                bugs.setLcmOcId(null);
            }
            //修改bug信息
            if(ObjectUtils.isEmpty(bugs.getBugStatus()) || !bugs.getBugStatus().equals(BugsStatus.CLOSE.getStatus())){
                //bug状态为空 and bug状态不为关闭修改当前处理人。
                bugs.setHandleStatus(handleStatus.equals("0")?"1":"0");
            }
            baseMapper.updateById(bugs);
            return AjaxResult.success("处理成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("处理bug异常:"+e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("处理异常，请联系it处理");
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult transferBug(Bugs bug) {
        try {
            List<Long> rdHandleId = bug.getRdHandle();
            Long bid = bug.getId();
            List<Long> ids = bug.getIds();
            if(CollectionUtils.isEmpty(rdHandleId)){
                return AjaxResult.error("转办人不能为空");
            }
            if(StringUtils.isEmpty(bug.getReason())){
                return AjaxResult.error("转办原因不能为空");
            }
            //获取登录用户信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();

            if(!ObjectUtils.isEmpty(bid)){//单个转办
                //查找最新的研发处理人
                List<BugsRdHandle> rdHandles = rdHandleMapper.findBugsRdHandleByBid(bid);
                if(CollectionUtils.isEmpty(rdHandles)){
                    return AjaxResult.error("找不到当前研发处理人");
                }
                //查询bug信息
                Bugs bugs = baseMapper.selectById(bid);
                String bugStatus = bugs.getBugStatus();
                if(bugStatus.equals(BugsStatus.CLOSE.getStatus())|| bugStatus.equals(BugsStatus.WAIVE.getStatus())){
                    return AjaxResult.error("bug当前状态不允许转办!");
                }

                //验证转办权限
                boolean flag = checkTransferPower(loginUser, bugs, rdHandles, bid);
                if(!flag){
                    return AjaxResult.error("你不是当前bug处理人,无权执行此操作");
                }

                List<Integer> collect = rdHandles.stream().map(item -> {
                    return item.getId();
                }).collect(Collectors.toList());
                //转办
                int i = rdHandleMapper.deleteBatchIds(collect);//先删除最新处理人
                if(i>0){//再插入最新研发处理人
                    String tranferUserId="";
                    for (Long uId : rdHandleId) {
                        BugsRdHandle bugsRdHandle = new BugsRdHandle();
                        bugsRdHandle.setBugId(bid);
                        bugsRdHandle.setStatus("1");//插入时为最新处理人
                        bugsRdHandle.setUserId(uId);//处理人
                        bugsRdHandle.setCreateUser(userId);
                        bugsRdHandle.setCreateTime(LocalDateTime.now());
                        rdHandleMapper.insert(bugsRdHandle);
                        if(StringUtils.isEmpty(tranferUserId)){
                            tranferUserId+=uId;
                        }else {
                            tranferUserId+=","+uId;
                        }
                    }
                    //查找最新的bug描述
                    BugDescription bugDescriptionByBid = descriptionMapper.findBugDescriptionByBid(bid);
                    //记录转办操作日志
                    TranferLog tranferLog = new TranferLog();
                    tranferLog.setBugId(bid);//bug对应的id
                    tranferLog.setBdId(bugDescriptionByBid.getId());//bug对应最新描述的id
                    tranferLog.setHandleUser(userId);
                    tranferLog.setTranferUser(tranferUserId);//转办接受人id,多个使用逗号隔开
                    tranferLog.setReason(bug.getReason());//转办原因
                    tranferLog.setCreateUser(userId);//创建人
                    tranferLog.setCreateTime(LocalDateTime.now());//创建时间
                    tranferLogMapper.insert(tranferLog);
                    //转办成功发送企业微信消息通知转办人
                    new Thread(()->{
                        List<String> jobNumber=new ArrayList<>();
                        for (Long aLong : rdHandleId) {
                            SysUser sysUser = userMapper.selectUserById(aLong);
                            if(!ObjectUtils.isEmpty(sysUser)){
                                String jobNumber1 = sysUser.getJobNumber();
                                if(!StringUtils.isEmpty(jobNumber1)){
                                    jobNumber.add(jobNumber1);
                                }
                            }
                        }
                        String userName="";
                        SysUser sysUser = userMapper.selectUserById(userId);
                        if(!ObjectUtils.isEmpty(sysUser)){
                            userName=sysUser.getUserName();
                        }
                        String msg="你好,"+userName+"向你转办了一个待处理的项目bug，bug编码为："+bugs.getBugCode();
                        String cause="转办原因："+bug.getReason();
                        String msg1="请你尽快登录bugList系统进行处理，谢谢。系统登录链接为："+paramConfig.getLink();
                        List<String> mesage=new ArrayList<>();
                        mesage.add(msg);
                        mesage.add(cause);
                        mesage.add(msg1);
                        weChatNoteUtils.sendWeChatNoteByJobNumber(jobNumber,mesage);
                    }).start();

                    return AjaxResult.success("转办成功");
                }else {
                    return AjaxResult.error("转办失败");
                }
            }else if(!CollectionUtils.isEmpty(ids)){//批量转办
                //用来存储没有转办权限操作的list
                List<String> powerFail=new ArrayList<>();
                //用来存储bug状态不允许转办的数据
                List<String> bugStatusFail=new ArrayList<>();
                //先验证权限
                for (Long bugId : ids) {
                    //查找最新的研发处理人
                    List<BugsRdHandle> rdHandles = rdHandleMapper.findBugsRdHandleByBid(bugId);
                    if(CollectionUtils.isEmpty(rdHandles)){
                        return AjaxResult.error("找不到当前研发处理人");
                    }
                    //查询bug信息
                    Bugs bugs = baseMapper.selectById(bugId);
                    String bugStatus = bugs.getBugStatus();
                    if(bugStatus.equals(BugsStatus.CLOSE.getStatus())|| bugStatus.equals(BugsStatus.WAIVE.getStatus())){
                        bugStatusFail.add(bugs.getBugCode());
                    }

                    //验证转办权限
                    boolean flag = checkTransferPower(loginUser, bugs, rdHandles, bugId);
                    if(!flag){
                        //没有权限操作
                        powerFail.add(bugs.getBugCode());
                    }
                }
                if(!CollectionUtils.isEmpty(bugStatusFail)){
                    return AjaxResult.error("bug编码为这些"+powerFail.toString()+"的bug当前状态不允许转办！");
                }
                if(!CollectionUtils.isEmpty(powerFail)){
                    return AjaxResult.error("你没有权限转办bug编码为这些"+powerFail.toString()+"的bug，你不是这些bug的当前处理人");
                }

                //用来存储转办失败的bug
                List<String> failTransfer=new ArrayList<>();
                //再执行转办操作
                for (Long id : ids) {
                    //查找最新的研发处理人
                    List<BugsRdHandle> rdHandles = rdHandleMapper.findBugsRdHandleByBid(id);
                    List<Integer> collect = rdHandles.stream().map(item -> {
                        return item.getId();
                    }).collect(Collectors.toList());
                    //转办
                    int i = rdHandleMapper.deleteBatchIds(collect);//先删除最新处理人
                    if(i>0){//再插入最新研发处理人
                        String tranferUserId="";
                        for (Long uId : rdHandleId) {
                            BugsRdHandle bugsRdHandle = new BugsRdHandle();
                            bugsRdHandle.setBugId(id);
                            bugsRdHandle.setStatus("1");//插入时为最新处理人
                            bugsRdHandle.setUserId(uId);//处理人
                            bugsRdHandle.setCreateUser(userId);
                            bugsRdHandle.setCreateTime(LocalDateTime.now());
                            rdHandleMapper.insert(bugsRdHandle);
                            if(StringUtils.isEmpty(tranferUserId)){
                                tranferUserId+=uId;
                            }else {
                                tranferUserId+=","+uId;
                            }
                        }
                        //查找最新的bug描述
                        BugDescription bugDescriptionByBid = descriptionMapper.findBugDescriptionByBid(id);
                        //记录转办操作日志
                        TranferLog tranferLog = new TranferLog();
                        tranferLog.setBugId(id);//bug对应的id
                        tranferLog.setBdId(bugDescriptionByBid.getId());//bug对应最新描述的id
                        tranferLog.setHandleUser(userId);
                        tranferLog.setTranferUser(tranferUserId);//转办接受人id
                        tranferLog.setReason(bug.getReason());//转办原因
                        tranferLog.setCreateUser(userId);//创建人
                        tranferLog.setCreateTime(LocalDateTime.now());//创建时间
                        tranferLogMapper.insert(tranferLog);
                    }else {
                        //查询bug信息
                        Bugs bugs = baseMapper.selectById(id);
                        failTransfer.add(bugs.getBugCode());
                    }
                }
                if(!CollectionUtils.isEmpty(failTransfer)){
                   return AjaxResult.warn("bug编码为这些"+failTransfer.toString()+"的bug转办失败");
                }

                //bug批量转办成功之后发送企业微信消息通知
                new Thread(()->{
                    List<String> bugCode=new ArrayList<>();
                    for (Long id : ids) {
                        Bugs bugs = baseMapper.selectById(id);
                        if(!ObjectUtils.isEmpty(bugs)){
                            bugCode.add(bugs.getBugCode());
                        }
                    }
                    List<String> jobNumber=new ArrayList<>();
                    for (Long aLong : rdHandleId) {
                        SysUser sysUser = userMapper.selectUserById(aLong);
                        if(!ObjectUtils.isEmpty(sysUser)){
                            String jobNumber1 = sysUser.getJobNumber();
                            if(!StringUtils.isEmpty(jobNumber1)){
                                jobNumber.add(jobNumber1);
                            }
                        }
                    }
                    String userName="";
                    SysUser sysUser = userMapper.selectUserById(userId);
                    if(!ObjectUtils.isEmpty(sysUser)){
                        userName=sysUser.getUserName();
                    }
                    String msg="你好,"+userName+"向你批量转办了待处理的项目bug，bug编码为："+bugCode.toString();
                    String cause="转办原因："+bug.getReason();
                    String msg1="请你尽快登录bugList系统进行处理，谢谢。系统登录链接为："+paramConfig.getLink();
                    List<String> mesage=new ArrayList<>();
                    mesage.add(msg);
                    mesage.add(cause);
                    mesage.add(msg1);
                    weChatNoteUtils.sendWeChatNoteByJobNumber(jobNumber,mesage);
                }).start();

                return AjaxResult.success("转办成功");

            }else {
                return AjaxResult.error("请选择需要转办的数据");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("转办异常："+e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("转办异常,请联系it处理");
        }
    }

    private boolean checkTransferPower(LoginUser loginUser,Bugs bugs,List<BugsRdHandle> rdHandles,Long bid){
        boolean admin = loginUser.getUser().isAdmin();
        Long userId = loginUser.getUserId();
        //验证是否是管理员
        Boolean flag=false;

        Boolean blAdmin=false;
        List<SysRole> roles = loginUser.getUser().getRoles();
        if(!CollectionUtils.isEmpty(roles)){
            for (SysRole role : roles) {
                String roleKey = role.getRoleKey();
                if(roleKey.equals(RoleKey.ADMIN.getCode())){
                    blAdmin=true;
                    break;
                }
            }
        }
        if(admin || blAdmin){
            flag=true;
        }else {
            //验证是否是bug创建人
            flag=checkBugCreate(bugs,userId);
            if(!flag){
                //验证是否为当前bug处理人
                String handleStatus = bugs.getHandleStatus();
                if(handleStatus.equals("0")){//当前处理为研发/npi
                    for (BugsRdHandle rdHandle : rdHandles) {
                        if(rdHandle.getUserId().equals(userId)){
                            flag=true;
                            break;
                        }
                    }
                }else {//当前处理为创建人
                    List<BugsQdeHandle> qdeHandles = qdeHandleMapper.findBugsQdeHandleByBid(bid);
                    if(!CollectionUtils.isEmpty(qdeHandles)){
                        for (BugsQdeHandle qdeHandle : qdeHandles) {
                            if(qdeHandle.getUserId().equals(userId)){
                                flag=true;
                                break;
                            }
                        }
                    }
                }
            }
        }
        return flag;
    }

    @Override
    public AjaxResult bugHandleLogList(Long id) {
        if(ObjectUtils.isEmpty(id)){
            return AjaxResult.error("查询的数据不能为空");
        }
        List<BugsHandleLog> bugsHandleLogs = bugsHandleLogMapper.handleLogList(id);
        return AjaxResult.success(bugsHandleLogs);
        //查询bug描述日志数据
//        List<BugDescription> descriptionsLog = descriptionMapper.bugDescriptionLogByBid(id);
//        List<BugAnalysis> bugAnalysesLog = analysisMapper.bugAnalysisLogByBid(id);
//        if(!CollectionUtils.isEmpty(bugAnalysesLog)){
//            for (BugAnalysis bugAnalysis : bugAnalysesLog) {
//                BugDescription bugDescription = new BugDescription();
//                BeanUtils.copyProperties(bugAnalysis,bugDescription);
//                descriptionsLog.add(bugDescription);
//            }
//        }
//        //根据时间升序排序
//        List<BugDescription> sortList = descriptionsLog.stream().sorted(Comparator.comparing(BugDescription::getCreateTime,Comparator.nullsLast(Comparator.naturalOrder()))).collect(Collectors.toList());
//        return AjaxResult.success(sortList);
    }

    @Override
    public List<ProjectBugVo> projectBugsList(ProjectBugVo projectBugVo) {
        List<ProjectBugVo> projectBugVos = bugsMapper.projectBugList(projectBugVo);
        //过滤掉html标签
        projectBugVos.stream().forEach(item->{
            String bugDescriptions= item.getBugDescriptions();
            String bugAnalysis = item.getBugAnalysis();
            String bugAnswer = item.getBugAnswer();

            if(!StringUtils.isEmpty(bugDescriptions)){
                //获取图片路径
                String src1 = com.pm.common.utils.StringUtils.filterImageSrc(bugDescriptions);
                if(!StringUtils.isEmpty(src1)){
                    if(src1.contains("/upload")){
                        String path = src1.substring(src1.lastIndexOf("/upload"));
                        item.setDImgPath(path);
                    }
                }
                //开始过滤
                String ds = com.pm.common.utils.StringUtils.filterHtmlTags(bugDescriptions).replaceAll(" ","");
                item.setBugDescriptions(ds);
            }
//            if(!StringUtils.isEmpty(bugAnalysis)){
//                //获取图片路径
//                String src2 = com.bl.common.utils.StringUtils.filterImageSrc(bugAnalysis);
//                if(!StringUtils.isEmpty(src2)){
//                    if(src2.contains("/upload")) {
//                        String path = src2.substring(src2.lastIndexOf("/upload"));
//                        item.setAImgPath(path);
//                    }
//                }
//                //开始过滤
//                String as = com.bl.common.utils.StringUtils.filterHtmlTags(bugAnalysis).replaceAll(" ","");
//                item.setBugAnalysis(as);
//            }
//            if(!StringUtils.isEmpty(bugAnswer)){
//                //获取图片路径
//                String src3 = com.bl.common.utils.StringUtils.filterImageSrc(bugAnswer);
//                if(!StringUtils.isEmpty(src3)){
//                    if(src3.contains("/upload")) {
//                        String path = src3.substring(src3.lastIndexOf("/upload"));
//                        item.setCImgPath(path);
//                    }
//                }
//                //开始过滤
//                String bas = com.bl.common.utils.StringUtils.filterHtmlTags(bugAnswer).replaceAll(" ","");
//                item.setBugAnswer(bas);
//            }
        });
        return projectBugVos;
    }

    /**
     * 导出第一版本的描述，最后关闭版本的分析与对策
     * */
    @Override
    public List<ProjectBugVo> projectBugsListTwo(ProjectBugVo projectBugVo) {
        List<ProjectBugVo> projectBugVos = bugsMapper.projectBugListTwo(projectBugVo);
        //过滤掉html标签
        projectBugVos.stream().forEach(item->{
            String bugDescriptions= item.getBugDescriptions();
            String bugAnalysis = item.getBugAnalysis();
            String bugAnswer = item.getBugAnswer();
            if(!StringUtils.isEmpty(bugDescriptions)){
                //获取图片路径
                String src1 = com.pm.common.utils.StringUtils.filterImageSrc(bugDescriptions);
                if(!StringUtils.isEmpty(src1)){
                    if(src1.contains("/upload")){
                        String path = src1.substring(src1.lastIndexOf("/upload"));
                        item.setDImgPath(path);
                    }
                }
                //开始过滤
                String ds = com.pm.common.utils.StringUtils.filterHtmlTags(bugDescriptions).replaceAll(" ","");
                item.setBugDescriptions(ds);
            }
//            if(!StringUtils.isEmpty(bugAnalysis)){
//                //获取图片路径
//                String src2 = com.bl.common.utils.StringUtils.filterImageSrc(bugAnalysis);
//                if(!StringUtils.isEmpty(src2)){
//                    if(src2.contains("/upload")) {
//                        String path = src2.substring(src2.lastIndexOf("/upload"));
//                        item.setAImgPath(path);
//                    }
//                }
//                //开始过滤
//                String as = com.bl.common.utils.StringUtils.filterHtmlTags(bugAnalysis).replaceAll(" ","");
//                item.setBugAnalysis(as);
//            }
//            if(!StringUtils.isEmpty(bugAnswer)){
//                //获取图片路径
//                String src3 = com.bl.common.utils.StringUtils.filterImageSrc(bugAnswer);
//                if(!StringUtils.isEmpty(src3)){
//                    if(src3.contains("/upload")) {
//                        String path = src3.substring(src3.lastIndexOf("/upload"));
//                        item.setCImgPath(path);
//                    }
//                }
//                //开始过滤
//                String bas = com.bl.common.utils.StringUtils.filterHtmlTags(bugAnswer).replaceAll(" ","");
//                item.setBugAnswer(bas);
//            }
        });
        return projectBugVos;
    }

    @Override
    public AjaxResult delBugById(Long id) {
        try {
            if(ObjectUtils.isEmpty(id)){
                return AjaxResult.error("操作的数据不能为空");
            }
            Bugs bugs = baseMapper.selectById(id);
            LoginUser loginUser = SecurityUtils.getLoginUser();
            boolean admin = loginUser.getUser().isAdmin();
            boolean flag=false;//是否有权限的标注

            Boolean blAdmin=false;//是否是系统管理员标注
            List<SysRole> roles = loginUser.getUser().getRoles();
            if(!CollectionUtils.isEmpty(roles)){
                for (SysRole role : roles) {
                    String roleKey = role.getRoleKey();
                    if(roleKey.equals(RoleKey.ADMIN.getCode())){
                        blAdmin=true;
                        break;
                    }
                }
            }
            if(admin || blAdmin){
                flag=true;
            }else {
                if(bugs.getCreateUser().equals(loginUser.getUserId())){//创建bug的人可以删除
                    flag=true;
                }
            }
            if(!flag){
                return AjaxResult.error("你不是bug创建人不能删除bug");
            }
            //验证bug状态
//        if(!bugs.getBugStatus().equals(BugsStatus.OPEN.getStatus())){
//            return AjaxResult.error("bug正在处理中，不能删除");
//        }
            bugs.setUpdateUser(loginUser.getUserId());
            bugs.setUpdateTime(LocalDateTime.now());
            bugs.setDelFlag("2");//删除
            baseMapper.updateById(bugs);
            return AjaxResult.success("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("bug删除异常:"+e);
            return AjaxResult.error("bug删除异常");
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult resetBugById(Long id) {
        try {
            if(ObjectUtils.isEmpty(id)){
                return AjaxResult.error("操作的数据不能为空");
            }
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();

            //判断用户是否是管理员身份
            boolean admin = loginUser.getUser().isAdmin();
            boolean flag=false;//是否有权限的标注
            List<SysRole> roles = loginUser.getUser().getRoles();
            if(!CollectionUtils.isEmpty(roles)){
                for (SysRole role : roles) {
                    String roleKey = role.getRoleKey();
                    if(roleKey.equals(RoleKey.ADMIN.getCode())){
                        flag=true;
                        break;
                    }
                }
            }
            if(admin||flag){
                flag=true;
            }
            if(!flag){
                return AjaxResult.error("你没有权限重置waive了的bug!");
            }

            //根据bug id 查询对应的处理日志（降序查询两条，状态重置到waive状态之前）
            List<BugsHandleLog> bugsHandleLogs = bugsHandleLogMapper.handleLogListByPage(id);
            BugsHandleLog log = bugsHandleLogs.get(1);//获取waive之前的数据
            Bugs bugs = baseMapper.selectById(id);//查询项目bug
            bugs.setBugStatus(log.getBugStatus());//重置的状态
            bugs.setUpdateUser(userId);//修改人
            bugs.setUpdateTime(LocalDateTime.now());//修改时间
            baseMapper.updateById(bugs);
            //修改之后记录操作日志
            //记录bug处理日志
            BugsHandleLog bugsHandleLog = new BugsHandleLog();
            bugsHandleLog.setBugId(bugs.getId());//bugId
            bugsHandleLog.setBugStatus(bugs.getBugStatus());//状态
            bugsHandleLog.setBugTitle(log.getBugTitle());//标题使用日志的 会变
            bugsHandleLog.setVersion(log.getVersion());//版本使用日志的 会变
            bugsHandleLog.setHandleUser(userId);
            bugsHandleLog.setRemark("waive状态下重置bug状态");
            bugsHandleLog.setCreateTime(LocalDateTime.now());
            handleLogMapper.insert(bugsHandleLog);
            return AjaxResult.success("重置成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("重置bug异常:"+e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("重置bug异常，请联系it处理");
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult activationBugById(Long id) {

        try {
            if(ObjectUtils.isEmpty(id)){
                return AjaxResult.error("操作的数据不能为空");
            }
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();
            //根据id 查找bug
            Bugs bugs = baseMapper.selectById(id);
            //判断用户是否是管理员身份
            boolean admin = loginUser.getUser().isAdmin();
            boolean flag=false;//是否有权限的标注
            List<SysRole> roles = loginUser.getUser().getRoles();
            if(!CollectionUtils.isEmpty(roles)){
                for (SysRole role : roles) {
                    String roleKey = role.getRoleKey();
                    if(roleKey.equals(RoleKey.ADMIN.getCode())){
                        flag=true;
                        break;
                    }
                }
            }
            if(admin||flag || bugs.getCreateUser().equals(userId)){//管理员以及bug创建人才有权限激活已经关闭的bug
                flag=true;
            }
            if(!flag){
                return AjaxResult.error("你没有权限激活已经关闭了的bug!");
            }

            //执行激活操作
            bugs.setBugStatus(BugsStatus.TRACKING.getStatus());//设置TRACKING
            bugs.setHandleStatus("1");//激活之后bug当前处理人为提报人
            bugs.setUpdateTime(LocalDateTime.now());
            bugs.setUpdateUser(userId);
            baseMapper.updateById(bugs);

            //修改分析标注
            BugAnalysis bugAnalysis = analysisMapper.selectBugAnalysisByBid(id);
            bugAnalysis.setIsClose("0");//激活之后，关闭标注为0
            analysisMapper.updateById(bugAnalysis);
            //记录bug处理日志
            BugsHandleLog bugsHandleLog = new BugsHandleLog();
            bugsHandleLog.setBugId(bugs.getId());
            bugsHandleLog.setBugStatus(bugs.getBugStatus());
            bugsHandleLog.setBugTitle(bugs.getBugTitle());
            bugsHandleLog.setVersion(bugAnalysis.getVersion());//最新的版本
            bugsHandleLog.setHandleUser(userId);
            bugsHandleLog.setCreateTime(LocalDateTime.now());
            handleLogMapper.insert(bugsHandleLog);

            return AjaxResult.success("激活成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("激活bug异常:"+e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("激活bug异常");
        }
    }

    @Override
    @Transactional(rollbackFor = {Exception.class,RuntimeException.class})
    public AjaxResult batchImportBugs(List<ImportBug> list, Long pid) {
        try {
            Project project = projectMapper.selectById(pid);
            if(ObjectUtils.isEmpty(project)){
                return AjaxResult.error("导入失败：找不到对应的项目数据");
            }
            //获取登录用户信息
            LoginUser loginUser = SecurityUtils.getLoginUser();
            Long userId = loginUser.getUserId();//登录账号用户id
            List<SysRole> roles = loginUser.getUser().getRoles();
            Boolean identifyFlag=false;//bug创建标识标志
            if(!CollectionUtils.isEmpty(roles)){
                for (SysRole role : roles) {
                    if(role.getRoleKey().equals(RoleKey.NPI.getCode())){
                        identifyFlag=true;
                        break;
                    }
                }
            }

            String projectNo = project.getProjectNo();//项目编码
            AtomicInteger index=new AtomicInteger(1);//记录excel表格行数
            List<Bugs> listBugs=new ArrayList<>();//保存验证之后的bug数据
            //先验证数据
            for (ImportBug importBug : list) {
                int newIndex = index.incrementAndGet();//自增并且获取最新值
                String projectCode = importBug.getProjectCode();//导入的项目编码
                //验证导入的bug与当前传过来的项目id对应的项目编码是否一致
                if(StringUtils.isEmpty(projectCode)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的项目编码不能为空");
                }else {
                   if(!projectNo.equals(projectCode)){
                       return AjaxResult.error("导入失败：第"+newIndex+"行数据的项目编码与当前导入的项目的项目编码不匹配");
                   }
                }

                String level = importBug.getLevel();//严重程度
                String productStage = importBug.getProductStage();//产品阶段
                String problemType = importBug.getProblemType();//问题类别
                String bugVersion = importBug.getBugVersion();//fw版本
                String createUser = importBug.getCreateUser();//提报人姓名
                String createTime = importBug.getCreateTime();//提报时间
                String respon = importBug.getRespon();//责任人姓名
                String bugStatus = importBug.getBugStatus();//状态描述
                String closeTime = importBug.getCloseTime();//关闭时间字符串
                String descriptions = importBug.getDescriptions();//问题描述
                String analysis = importBug.getAnalysis();//问题分析
                String answer = importBug.getAnswer();//改善对策
                String closeVersion = importBug.getCloseVersion();//关闭版本
                String badPersentage = importBug.getBadPersentage();//不良率
                if(StringUtils.isEmpty(level)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的严重程度不能为空");
                }
                if(StringUtils.isEmpty(productStage)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的产品阶段不能为空");
                }
                if(StringUtils.isEmpty(problemType)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的问题类别不能为空");
                }
                if(StringUtils.isEmpty(bugVersion)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的fw版本不能为空");
                }
                if(StringUtils.isEmpty(respon)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的责任人不能为空");
                }
                if(StringUtils.isEmpty(bugStatus)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的bug状态不能为空");
                }
                if(StringUtils.isEmpty(descriptions)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的问题描述不能为空");
                }
                if(StringUtils.isEmpty(badPersentage)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的不良率不能为空");
                }
                //获取提交人
                Long qdeHandle=null;
                if(StringUtils.isEmpty(createUser)){//提交人为空，当前操作人为提交人
                    qdeHandle=userId;
                }else {
                    SysUser user = userMapper.selectUserByNickName(createUser);//根据名字查询提报人
                    if(ObjectUtils.isEmpty(user)){
                        return AjaxResult.error("导入失败：第"+newIndex+"行数据，系统找不到名为'"+createUser+"'的提报人");
                    }
                    qdeHandle=user.getUserId();
                }
                //获取责任人
                String[] responNames = respon.split(",");
                List<Long> responIds=new ArrayList<>();
                for (String responName : responNames) {
                    SysUser user1 = userMapper.selectUserByNickName(responName);
                    if(ObjectUtils.isEmpty(user1)){
                        return AjaxResult.error("导入失败：第"+newIndex+"行数据，系统找不到名为'"+responName+"'的责任人");
                    }
                    responIds.add(user1.getUserId());
                }
                // 查询bug状态值
                String bstatus = dictDataMapper.selectDictLabel(DictDateKey.BUGS_STATUS.getKey(),bugStatus);
                if(StringUtils.isEmpty(bstatus)){
                    return AjaxResult.error("导入失败：第"+newIndex+"行数据的bug状态查找不到对应的bug状态值");
                }

                //提报日期转换
                LocalDateTime create_time=null;
                if(!StringUtils.isEmpty(createTime)){
                    try {
                        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
                        Date dlDate = dateFormat.parse(createTime);
                        Instant instant = dlDate.toInstant(); // 将Date对象转换为Instant对象
                        create_time = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); // 通过Instant对象创建LocalDateTime对象
                    } catch (ParseException e) {
                        e.printStackTrace();
                        log.error("导入失败：批量导入bug,提报日期转换异常");
                        return AjaxResult.error("导入失败：第"+newIndex+"行数据的提报日期转换异常，请将改善日期单元格的格式改为（text/文本）格式；例如：2024-03-27");
                    }
                }
                //改善日期
                LocalDateTime close_time=null;
                if(bstatus.equals(BugsStatus.CLOSE.getStatus())){//关闭状态，分析与描述不能为空
                    if(StringUtils.isEmpty(analysis)){
                        return AjaxResult.error("导入失败：bug状态为Close状态，第"+newIndex+"行数据的问题分析不能为空");
                    }
                    if(StringUtils.isEmpty(answer)){
                        return AjaxResult.error("导入失败：bug状态为Close状态，第"+newIndex+"行数据的改善对策不能为空");
                    }
                    if(StringUtils.isEmpty(closeTime)){
                        return AjaxResult.error("导入失败：bug状态为Close状态，第"+newIndex+"行数据的改善时间不能为空");
                    }
                    if(StringUtils.isEmpty(closeVersion)){
                        return AjaxResult.error("导入失败：bug状态为Close状态，第"+newIndex+"行数据的close fw版本不能为空");
                    }
                    if(StringUtils.isEmpty(createTime)){
                        return AjaxResult.error("导入失败：bug状态为Close状态，第"+newIndex+"行数据的提报日期不能为空");
                    }
                    //改善时间转换
                    try {
                        SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
                        Date dlDate = dateFormat.parse(closeTime);
                        Instant instant = dlDate.toInstant(); // 将Date对象转换为Instant对象
                        close_time = LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); // 通过Instant对象创建LocalDateTime对象
                    } catch (ParseException e) {
                        e.printStackTrace();
                        log.error("导入失败：批量导入bug,第"+newIndex+"行数据的改善日期转换异常");
                        return AjaxResult.error("导入失败：第"+newIndex+"行数据的改善时间转换异常，请将改善日期单元格的格式改为（text/文本）格式；例如：2024-03-27");
                    }
                    //验证提报日期不能大于改善日期
                    if(close_time.isBefore(create_time)){
                        log.error("导入失败：批量导入bug,提报日期大于改善日期");
                        return AjaxResult.error("导入失败：第"+newIndex+"行数据的提报日期大于改善日期，请保证提报日期小于改善日期！");
                    }
                }
                if(ObjectUtils.isEmpty(create_time)){
                    //如果没有提报日期就设置今天
                    create_time=LocalDateTime.now();
                }


                Bugs bugs = new Bugs();
                BeanUtils.copyProperties(importBug,bugs);
                bugs.setPid(pid);//设置项目id
                bugs.setCreateTime(create_time);//设置提报日期
                bugs.setUpdateTime(close_time);//设置改善日期
                bugs.setQdeHandle(qdeHandle);//设置提报人
                bugs.setRdHandle(responIds);//设置责任人
                bugs.setBugStatus(bstatus);//设置bug状态
                bugs.setCreateUser(qdeHandle);//设置bug创建人
                if(identifyFlag){//bug标识
                    bugs.setIdentify("N");//工厂NPI标识(试投bug)
                }else {
                    bugs.setIdentify("T");//测试bug
                }
                listBugs.add(bugs);//验证完毕之后保存到list
            }
            //插入数据
            listBugs.stream().forEach(bugs -> {
                Long qdeHandle = bugs.getQdeHandle();//提报人
                List<Long> rdHandle = bugs.getRdHandle();//责任人
                LocalDateTime updateTime = bugs.getUpdateTime();//改善日期（最后关闭bug的时间）

                //插入bug
                long bid = YitIdHelper.nextId();
                bugs.setId(bid);//设置bug id
                bugs.setBugCode(createCode());//设置bugCode
                if(bugs.getBugStatus().equals(BugsStatus.CLOSE.getStatus())){
                    bugs.setHandleStatus("1");//导入的关闭bug,有可能会被激活，激活的bug当前处理人为提交人
                }
                baseMapper.insert(bugs);

                // 插入数据
                //责任人
                for (Long aLong : rdHandle) {
                    BugsRdHandle bugsRdHandle = new BugsRdHandle();
                    bugsRdHandle.setBugId(bid);
                    bugsRdHandle.setStatus("1");//插入时为最新处理人
                    bugsRdHandle.setUserId(aLong);//处理人
                    bugsRdHandle.setCreateUser(userId);
                    bugsRdHandle.setCreateTime(LocalDateTime.now());
                    rdHandleMapper.insert(bugsRdHandle);
                }

                //提报人
                BugsQdeHandle bugsQdeHandle = new BugsQdeHandle();
                bugsQdeHandle.setBugId(bid);
                bugsQdeHandle.setStatus("1");//插入时为最新处理人
                bugsQdeHandle.setUserId(qdeHandle);//品质指派人就是创建人
                bugsQdeHandle.setCreateUser(userId);
                bugsQdeHandle.setCreateTime(LocalDateTime.now());
                qdeHandleMapper.insert(bugsQdeHandle);


                //判断导入的bug状态
                //插入描述之后插入bug分析
                if(bugs.getBugStatus().equals(BugsStatus.CLOSE.getStatus())){//关闭状态的bug

                    //插入bugs之后添加bugs描述
                    BugDescription bugDescription = new BugDescription();
                    bugDescription.setBugId(bid);
                    bugDescription.setDescriptions(bugs.getDescriptions());
                    bugDescription.setStatus("1");//发布的状态
                    bugDescription.setVersion(bugs.getCloseVersion());//描述重点版本是关闭版本
                    bugDescription.setCreateUser(userId);
                    bugDescription.setHandleUser(qdeHandle);//创建人
                    bugDescription.setCreateTime(LocalDateTime.now());
                    descriptionMapper.insert(bugDescription);

                    //插入bugs描述之后插入bug分析
                    BugAnalysis bugAnalysis = new BugAnalysis();
                    bugAnalysis.setBugId(bid);
                    bugAnalysis.setBdId(bugDescription.getId());
                    bugAnalysis.setAnalysis(bugs.getAnalysis());//分析
                    bugAnalysis.setBugAnswer(bugs.getAnswer());//对策
                    bugAnalysis.setVersion(bugs.getCloseVersion());//版本
                    bugAnalysis.setStatus("1");//发布的状态
                    bugAnalysis.setHandleUser(rdHandle.get(0));//责任人(默认第一个人)
                    bugAnalysis.setCreateTime(updateTime);//改善时间
                    //关闭状态的bug，分析要设置关闭标识
                    bugAnalysis.setIsClose("1");
                    analysisMapper.insert(bugAnalysis);
                }else {//新增的bug

                    String bugVersion = bugs.getBugVersion();
                    //插入bugs之后添加bugs描述
                    BugDescription bugDescription = new BugDescription();
                    bugDescription.setBugId(bid);//设置bug id
                    bugDescription.setDescriptions(bugs.getDescriptions());
                    bugDescription.setStatus("1");//发布的状态
                    bugDescription.setVersion(bugVersion);
                    bugDescription.setCreateUser(userId);
                    bugDescription.setHandleUser(qdeHandle);
                    bugDescription.setCreateTime(LocalDateTime.now());
                    descriptionMapper.insert(bugDescription);

                    //插入描述之后插入预确认的bug分析
                    BugAnalysis bugAnalysis = new BugAnalysis();
                    bugAnalysis.setBugId(bid);//设置bug id
                    bugAnalysis.setBdId(bugDescription.getId());//设置bug描述id
                    bugAnalysis.setStatus("0");//草稿的状态
                    analysisMapper.insert(bugAnalysis);

                    //记录bug处理日志
                    BugsHandleLog bugsHandleLog = new BugsHandleLog();
                    bugsHandleLog.setBugId(bid);
                    bugsHandleLog.setBugStatus(bugs.getBugStatus());
                    bugsHandleLog.setBugTitle(bugs.getBugTitle());
                    bugsHandleLog.setHandleStatus("1");//新建时的处理人身份为品质/NPI
                    bugsHandleLog.setVersion(bugs.getBugVersion());
                    bugsHandleLog.setHandleUser(userId);
                    bugsHandleLog.setCreateTime(LocalDateTime.now());
                    handleLogMapper.insert(bugsHandleLog);

                    //添加完毕之后，发送企业微信消息通知
                    new Thread(()->{
                        List<String> jobNumber=new ArrayList<>();
                        for (Long aLong : rdHandle) {
                            SysUser sysUser = userMapper.selectUserById(aLong);
                            if(!ObjectUtils.isEmpty(sysUser)){
                                String jobNumber1 = sysUser.getJobNumber();
                                if(!StringUtils.isEmpty(jobNumber1)){
                                    jobNumber.add(jobNumber1);
                                }
                            }
                        }
                        String userName="";
                        SysUser sysUser = userMapper.selectUserById(userId);
                        if(!ObjectUtils.isEmpty(sysUser)){
                            userName=sysUser.getUserName();
                        }
                        String msg="你好,"+userName+"向你提报了一个待处理的项目bug，bug编码为："+bugs.getBugCode();
                        String msg1="请你尽快登录bugList系统进行处理，谢谢。系统登录链接为："+paramConfig.getLink();
                        List<String> mesage=new ArrayList<>();
                        mesage.add(msg);
                        mesage.add(msg1);
                        weChatNoteUtils.sendWeChatNoteByJobNumber(jobNumber,mesage);
                    }).start();
                }
            });
            return AjaxResult.success("导入成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导入失败：批量导入bug数据异常，"+e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚事务
            return AjaxResult.error("导入失败：批量导入bug数据异常，"+e.getMessage());
        }
    }

    @Override
    public List<List<Object>> selectBugsCount(Bugs bugs) {

        List<List<Object>> mapDate=new ArrayList<>();
        //获取用户信息
        LoginUser loginUser = SecurityUtils.getLoginUser();
        //判断用户身份
        List<SysRole> roles = loginUser.getUser().getRoles();
        Boolean rdFlag=false;
        Boolean qdeFlag=false;
        Boolean npiFlag=false;
        if(!CollectionUtils.isEmpty(roles)){
            for (SysRole role : roles) {
                String roleKey = role.getRoleKey();
                if(roleKey.equals(RoleKey.DQE.getCode()) || roleKey.equals(RoleKey.DQA.getCode()) ||
                        roleKey.equals(RoleKey.ADMIN.getCode())){//品质
                    qdeFlag=true;
                    break;
                }else if(roleKey.equals(RoleKey.RD.getCode())){//研发
                    rdFlag=true;
                    break;
                }else if(roleKey.equals(RoleKey.NPI.getCode())){//npi角色
                    npiFlag=true;
                    break;
                }
            }
        }
        if(qdeFlag){//品质
            bugs.setQdeHandleUser(loginUser.getUserId());
            List<String> waiteList = baseMapper.selectAssignQdeBugsCount(bugs);
            List<String> noClose = baseMapper.selectQdeNoCloseCount(bugs);
            Integer wait=waiteList.size();
            Integer nC=noClose.size();
            Integer Unresolved=nC-wait;
            List<Object> qdeList1 = new ArrayList<>();
            qdeList1.add(nC);
            qdeList1.add("未关闭");
            List<Object> qdeList2 = new ArrayList<>();
            qdeList2.add(wait);
            qdeList2.add("待确认");
            List<Object> qdeList3 = new ArrayList<>();
            qdeList3.add(Unresolved);
            qdeList3.add("未解决");
            mapDate.add(qdeList1);
            mapDate.add(qdeList2);
            mapDate.add(qdeList3);
        }else if(rdFlag){//研发
            bugs.setRdHandleUser(loginUser.getUserId());
            List<Bugs> rdList = baseMapper.selectAssignRdBugsList(bugs);
            Integer wait=rdList.size();

//            List<Object> rdList1 = new ArrayList<>();
//            rdList1.add(0);
//            rdList1.add("未关闭");
//            mapDate.add(rdList1);

            List<Object> rdList2 = new ArrayList<>();
            rdList2.add(wait);
            rdList2.add("待确认");
            mapDate.add(rdList2);

//            List<Object> rdList3 = new ArrayList<>();
//            rdList3.add(0);
//            rdList3.add("未解决");
//            mapDate.add(rdList3);
        }else if(npiFlag){//npi
            bugs.setQdeHandleUser(loginUser.getUserId());
            bugs.setRdHandleUser(loginUser.getUserId());
            List<String> NPIList = baseMapper.selectAssignNpiBugCount(bugs);
            Integer wait=NPIList.size();

//            List<Object> npiList1 = new ArrayList<>();
//            npiList1.add(0);
//            npiList1.add("未关闭");
//            mapDate.add(npiList1);

            List<Object> npiList2 = new ArrayList<>();
            npiList2.add(wait);
            npiList2.add("待确认");
            mapDate.add(npiList2);

//            List<Object> npiList3 = new ArrayList<>();
//            npiList3.add(0);
//            npiList3.add("未解决");
//            mapDate.add(npiList3);

        }
        return mapDate;
    }

    @Override
    public AjaxResult getExceptionTypeDate() {
        List<List<Object>> result=new ArrayList<>();
        List<JSONObject> jsonObjects = baseMapper.selectExceptionTypeDate();
        ArrayList<Object> object = new ArrayList<>();
        object.add("数量");
        object.add("exceptionCode");
        result.add(object);
        if(!CollectionUtils.isEmpty(jsonObjects)){
            for (JSONObject jsonObject : jsonObjects) {
                List<Object> list=new ArrayList<>();
                Integer value = jsonObject.getInteger("value");
                String name = jsonObject.getString("name");
                list.add(value);
                if(StringUtils.isEmpty(name)){
                    list.add("异常类别为空");
                }else {
                    list.add(name);
                }
                result.add(list);
            }
        }
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findCloseACaseDateCount() {
        String code = RoleKey.DQE.getCode();
        List<JSONObject> total = baseMapper.selectDqeTotalCount(code);
        List<JSONObject> close = baseMapper.selectDqeCloseCount(code);
        List<List> result=new ArrayList<>();
        List<String> nameList=new ArrayList<>();
        List<Integer> tt=new ArrayList<>();
        List<Integer> cl=new ArrayList<>();
        List<BigDecimal> percent=new ArrayList<>();
        BigDecimal bigDecimal = new BigDecimal(100);
        for (JSONObject jsonObject : total) {
            String userName = jsonObject.getString("userName");
            for (JSONObject object : close) {
                String userName1 = object.getString("userName");
                if(userName.equals(userName1)){
                    Integer t = jsonObject.getInteger("num");
                    Integer c = object.getInteger("num");
                    BigDecimal p;
                    if(t.equals(0)){
//                        p= Double.valueOf(0);
                        cl.remove(object);//清除已经处理的数据
                        continue;
                    }else {
                        BigDecimal bd = new BigDecimal(c)
                                .divide(new BigDecimal(t), 2, RoundingMode.HALF_UP);
                        p= bd.multiply(bigDecimal);
                        nameList.add(userName);
                        tt.add(t);
                        cl.add(c);
                        percent.add(p);
                        cl.remove(object);//清除已经处理的数据
                    }
                }
            }
        }
        result.add(nameList);
        result.add(tt);
        result.add(cl);
        result.add(percent);
        return AjaxResult.success(result);
    }

    @Override
    public AjaxResult findExceptionCodeType(Bugs bugs) {
        List<JSONObject> jsonObjects = baseMapper.selectExceptionCodeType(bugs);
        List<List> result=new ArrayList<>();
        List<String> stringList=new ArrayList<>();
        List<Integer> numList=new ArrayList<>();
        if(!CollectionUtils.isEmpty(jsonObjects)){
            for (JSONObject jsonObject : jsonObjects) {
                String codeType = jsonObject.getString("codeType");
                Integer num = jsonObject.getInteger("num");
                if(StringUtils.isEmpty(codeType)){
                    codeType="空数据";
                }
                stringList.add(codeType);
                numList.add(num);
            }
            result.add(stringList);
            result.add(numList);
        }
        return AjaxResult.success(result);
    }

    @Override
    public List<Bugs> findApproveWaiveBug() {
        Long userId = SecurityUtils.getUserId();
        boolean admin = SecurityUtils.isAdmin(userId);
        if(admin){
            userId=null;
        }
        return baseMapper.DqeSelectApproveWaiveBug(BugsStatus.APPROVER_WAIVE.getStatus(),userId);
    }

    @Override
    public List<Bugs> findWaiveRecord(Long pid,String putOATab) {
        Long userId = SecurityUtils.getUserId();
        boolean admin = SecurityUtils.isAdmin(userId);
        //判断可以查询全部waive记录的角色（除了研发/Npi，因为研发/Npi需要推送自己申请waive的数据到OA）
        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        boolean isRdNpi=false;
        if(!CollectionUtils.isEmpty(roles)){
            for (SysRole role : roles) {
                String roleKey = role.getRoleKey();
                if( roleKey.equals(RoleKey.RD.getCode()) || roleKey.equals(RoleKey.NPI.getCode()) ){
                    isRdNpi=true;
                }
            }
        }
        if(admin || !isRdNpi){
            userId=null;
        }
        return baseMapper.RdApproveWaiveBug(BugsStatus.APPROVER_WAIVE.getStatus(),BugsStatus.WAIVE.getStatus(),userId,pid,putOATab);
    }

    @Override
    public AjaxResult putBugsToOaWaive(OaWaiveParam oaWaiveParam) {
        try {
            List<Long> bids = oaWaiveParam.getBids();
            Long pid = oaWaiveParam.getPid();
            if(ObjectUtils.isEmpty(pid)|| CollectionUtils.isEmpty(bids)){
                return AjaxResult.error("项目数据/bug数据不能为空");
            }

            //验证bug数据是否有重复推送oa的数据
            List<WavieOrder> wavieOrders = wavieOrderMapper.ifPutOaWaive(bids);
            if(!CollectionUtils.isEmpty(wavieOrders)){
                List<Long> collect = wavieOrders.stream().map(WavieOrder::getBId).collect(Collectors.toList());
                //去掉重复推送的数据
                bids.removeAll(collect);
            }

            Long userId = SecurityUtils.getUserId();
            String jobNumber = SecurityUtils.getLoginUser().getUser().getJobNumber();
            //根据pid查询对应的项目数据
            Project project = projectMapper.selectById(pid);
            String rdDirector = oaWaiveParam.getRdDirector();
            String productManager = oaWaiveParam.getProductManager();
            String dqaManager = oaWaiveParam.getDqaManager();
            String managerDecision = oaWaiveParam.getManagerDecision();
            String pjManage = project.getPjManage();//项目经理

            JSONObject param = new JSONObject();
            param.put("fd_productModel",project.getModel());//机型
            param.put("fd_projectNo",project.getProjectNo());//项目编码
            param.put("fd_clientName",oaWaiveParam.getClientName());
            param.put("fd_productStage",oaWaiveParam.getProductStage());//产品阶段
            param.put("fd_fwVersion",oaWaiveParam.getFwVersion());//fw版本
            param.put("fd_scaler",oaWaiveParam.getScaler());//scaler字段
            param.put("fd_panelVersion",oaWaiveParam.getPanelVersion());//panel版本
            param.put("fd_powerSupple",project.getPowerSupply());//电源、适配器
            param.put("fd_productLine",oaWaiveParam.getProductLine());//产品线
            param.put("fd_3d0c5901c43182_text",pjManage);//项目经理
            param.put("fd_3d0f528680fa76_text",rdDirector);//研发总监
            param.put("fd_3d0f52afc0279a_text",productManager);//产品经理
            param.put("fd_3d0f52cab1c2f6_text",dqaManager);//DQA主管
            param.put("fd_3be63f343493ca",managerDecision);
            JSONArray detail = new JSONArray();//明细表数据

            String fileName="fd_list.";
            if(!CollectionUtils.isEmpty(bids)){
                for (Long bid : bids) {
                    //根据bug id 查找对应的bug数据
                    JSONObject waiveBugInfo = baseMapper.getWaiveBugById(bid);
                    String category = waiveBugInfo.getString("category");
                    String grade = waiveBugInfo.getString("grade");
                    String descriptions = waiveBugInfo.getString("descriptions");
                    String waiveCause = waiveBugInfo.getString("waiveCause");
                    String correctiveAction = waiveBugInfo.getString("correctiveAction");
                    String rdName = waiveBugInfo.getString("rdName");
                    String presentDate = waiveBugInfo.getString("presentDate");
                    if(!StringUtils.isEmpty(descriptions)){//去掉描述的html标签
                        descriptions = com.pm.common.utils.StringUtils.filterHtmlTags(descriptions).replaceAll(" ","");
                    }
                    JSONObject detailRow = new JSONObject();//明细表数据行
                    detailRow.put(fileName+"fd_table_category",category);
                    detailRow.put(fileName+"fd_table_grade",grade);//问题等级
                    detailRow.put(fileName+"fd_table_problemDesc",descriptions);//原因描述
                    detailRow.put(fileName+"fd_table_rootCause",waiveCause);//rootCause
                    detailRow.put(fileName+"fd_table_rdNo_text",rdName);//研发名称
                    detailRow.put(fileName+"fd_table_correctiveAction",correctiveAction);
                    detailRow.put(fileName+"fd_table_presentDate",presentDate);//问题提出的时间
                    detail.add(detailRow);
                }
                param.put("fd_list",detail);
                //封装好参数之后推送oa
                String oaId = oaUtils.addReview2(jobNumber, param.toString(), null, null);
                if(!StringUtils.isEmpty(oaId)){
                    WavieOrder wavieOrder = new WavieOrder();
                    wavieOrder.setOaId(oaId);
                    //审批人拼接
                    String approverName="项目经理:"+pjManage+",研发总监:"+rdDirector+",产品经理:"+productManager+",DQA主管/经理:"+dqaManager;
                    wavieOrder.setApproverName(approverName);
                    wavieOrder.setOaStatus(OaStatus.IN_APPROVAL.getCode());
                    wavieOrder.setUpdateUser(userId);
                    wavieOrder.setUpdateTime(LocalDateTime.now());
                    QueryWrapper wrapper = new QueryWrapper<WavieOrder>();
                    //推送成功之后更新数据
                    for (Long bid : bids) {
                        wrapper.clear();
                        wrapper.eq("b_id",bid);
                        wavieOrderMapper.update(wavieOrder,wrapper);
                    }
                }
                return AjaxResult.success("推送成功");
            }else {
                return AjaxResult.error("所选的bug数据已推送过OA审核，请勿重复推送");
            }
        }catch (UtilException e) {
            e.printStackTrace();
            log.error("oa系统返回异常:"+e);
            return AjaxResult.error("oa系统返回异常:"+e.getMessage());
        }catch (Exception e) {
            e.printStackTrace();
            log.error("推送oa异常:"+e);
            return AjaxResult.error("推送oa异常");
        }
    }

    @Override
    public AjaxResult queryTotalBugByProject(JSONObject param) {
        List<JSONObject> list =  bugsMapper.queryTotalBugByProject(param);
        int totalNum = 0;
        int doneNum = 0;
        int toDoNum = 0;
        int waivedNum = 0;

        for (JSONObject item : list) {
            int num = item.getIntValue("num");
            switch (item.getString("status")){
                case "30":
                    waivedNum =  num ;
                    break;
                case "40":
                    doneNum =  num ;
                    break;
                default:
                    toDoNum = toDoNum+num;
                    break;
            }
        }
        totalNum = doneNum+toDoNum+waivedNum;
        JSONObject obj = new JSONObject();
        obj.put("waivedNum",waivedNum);
        obj.put("doneNum",doneNum);
        obj.put("toDoNum",toDoNum);
        obj.put("totalNum",totalNum);

        BigDecimal doneRate =doneNum == 0?  BigDecimal.ZERO:BigDecimal.valueOf(doneNum*100).divide(BigDecimal.valueOf(totalNum),0,BigDecimal.ROUND_HALF_UP);

        obj.put("doneRate",doneRate);

        return AjaxResult.success(obj);
    }

    @Override
    public AjaxResult queryTotalBugTypeByProject(JSONObject param) {
        List<JSONObject> list = bugsMapper.queryTotalBugTypeByProject(param);
        return AjaxResult.success(list);
    }




    public synchronized String createCode(){
        //生成唯一单号
        SimpleDateFormat simpleFormat =new SimpleDateFormat("YYYY-MM-dd");
        String format = simpleFormat.format(new Date());
        format=format.replaceAll("-","");
        String proofingKey="bugsCode"+format;
        String o = (String) redisTemplate.opsForValue().get(proofingKey);
        String str="";
        if(org.springframework.util.ObjectUtils.isEmpty(o)){
            o="0";
            redisTemplate.opsForValue().set(proofingKey,o,24, TimeUnit.HOURS);
            return "B"+format+"000"+o;
        }else {
            Integer code=Integer.valueOf(o)+1;
            str=str+code;
            int length = str.length();
            for (int i = 0; i < 4-length; i++) {
                str="0"+str;
            }
            redisTemplate.opsForValue().set(proofingKey,code+"",24, TimeUnit.HOURS);
            return "B"+format+str;
        }
    }

}
